package com.xuqm.base.ui;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;

import androidx.annotation.ColorRes;
import androidx.annotation.DrawableRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;

import com.gyf.immersionbar.BarHide;
import com.gyf.immersionbar.ImmersionBar;
import com.xuqm.base.R;
import com.xuqm.base.common.AppManager;
import com.xuqm.base.databinding.ActivityBaseBinding;
import com.xuqm.base.ui.callback.UiCallback;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public abstract class BaseActivity<V extends ViewDataBinding> extends AppCompatActivity implements UiCallback {

    protected String TAG = this.getClass().getSimpleName();
    protected Activity mContext;
    private V binding;

    private ActivityBaseBinding baseBinding;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AppManager.getInstance().pushActivity(this);
        mContext = this;
        editText.clear();
        views.clear();
        if (getLayoutId() == 0) {//没有layout的时候，act自己写布局
            ImmersionBar.with(this)
                    .init();
            setContentView();
        } else if (showStatus() != -1) {//没有toolbar但是有状态栏的情况
            bindUi(getLayoutId());
            ImmersionBar.with(this)
                    .titleBar(binding.getRoot()) //指定标题栏view
                    .statusBarColor(showStatus())
                    .autoStatusBarDarkModeEnable(true)
                    .init();
        } else if (transparentStatusBar()) {//透明状态栏，但是显示状态栏的内容
            bindUi(getLayoutId());
            ImmersionBar.with(this).transparentBar()
                    .titleBar(binding.getRoot().findViewWithTag("top_status"))
                    .init();
        } else if (fullscreen()) {//全屏，什么都不显示
            bindUi(getLayoutId());
            ImmersionBar.with(this)
                    .fullScreen(true)
                    .hideBar(BarHide.FLAG_HIDE_STATUS_BAR)
                    .init();
        } else {//使用base提供的toolbar
            baseBinding = DataBindingUtil.setContentView(mContext, R.layout.activity_base);
            ImmersionBar.with(this)
                    .transparentBar()
                    .hideBar(BarHide.FLAG_HIDE_NAVIGATION_BAR)
                    .titleBar(baseBinding.baseToolbar) //指定标题栏view
                    .init();
            binding = DataBindingUtil.inflate(getLayoutInflater(), getLayoutId(), baseBinding.activityRootView, true);
        }
        if (null != baseBinding) {
            baseBinding.baseToolbar.backBtnPressed(this::backBtnPressed);
        }
        initView(savedInstanceState);
        initData();
        lateInitView();
    }

    @NonNull
    public V getBinding() {
        return binding;
    }

    public ActivityBaseBinding getBaseBinding() {
        return baseBinding;
    }

    /**
     * 导航栏展示的内容
     *
     * @param titleId 标题
     */
    public void setTitleText(@StringRes int titleId) {
        setTitleText(getText(titleId));
    }

    /**
     * 导航栏展示的内容
     *
     * @param title 标题
     */
    public void setTitleText(CharSequence title) {
        if (null == baseBinding) {
            return;
        }
        baseBinding.baseToolbar.setTitle(title);
    }

    /**
     * 导航栏右上角按钮
     *
     * @param title 标题
     */
    public void setConfirmText(CharSequence title, View.OnClickListener listener) {
        if (null == baseBinding) {
            return;
        }
        baseBinding.baseToolbar.getConfirmBtn().setVisibility(View.VISIBLE);
        baseBinding.baseToolbar.getConfirmBtn().setText(title);
        baseBinding.baseToolbar.getConfirmBtn().setOnClickListener(listener);
    }

    /**
     * 设置标题颜色
     *
     * @param color 标题颜色
     */
    public void setTextColor(int color) {
        if (null == baseBinding) {
            return;
        }
        baseBinding.baseToolbar.setTextColor(color);
    }

    /**
     * 设置返回图标颜色
     *
     * @param iconTintColor 返回图标颜色
     */
    public void setIconTintColor(int iconTintColor) {
        if (null == baseBinding) {
            return;
        }
        baseBinding.baseToolbar.setIconTintColor(iconTintColor);
    }

    public void setIconDraw(@DrawableRes int resId) {
        if (null == baseBinding) {
            return;
        }
        baseBinding.baseToolbar.getBackBtn().setImageResource(resId);
    }

    /**
     * 是否展示返回按钮
     *
     * @param showBack 是否展示返回按钮
     */
    public void showBack(boolean showBack) {
        if (null == baseBinding) {
            return;
        }
        baseBinding.baseToolbar.setShowBack(showBack);
    }

    /**
     * 是否显示导航栏下面的线
     *
     * @param showLine 是否显示导航栏下面的线
     */
    public void showLine(boolean showLine) {
        if (null == baseBinding) {
            return;
        }
        baseBinding.baseToolbar.setShowLine(showLine);
    }


    public void backBtnPressed() {
        finish();
    }


    protected void bindUi(@LayoutRes int layoutResID) {
        binding = DataBindingUtil.setContentView(mContext, layoutResID);
    }

    /**
     * 如果不提供layoutId{@link #getLayoutId()} 则可以重写这个方法自己布局
     */
    @Override
    public void setContentView() {

    }

    @Override
    public void initView(Bundle savedInstanceState) {

    }

    @Override
    public void initData() {

    }

    /**
     * 这个init方法，在initData之后执行，有一些view相关的设置，需要数据信息
     */
    public void lateInitView() {

    }

    /**
     * 是否需要展示statusBar，默认为false，使用默认布局展示toolbar
     * false的话，可以自定义toolbar
     *
     * @return statusBar 的颜色
     */
    @Override
    @ColorRes
    public int showStatus() {
        return -1;
    }

    /**
     * 如果返回true，则状态栏变成透明状态，但是状态栏的文字还显示
     * 使用透明状态栏  布局必须指定一个  android:tag="top_status"
     * 最好是第一个子元素指定，可以自动设置padding
     *
     * @return 是否需要设置状态栏为透明状态
     */
    @Override
    public boolean transparentStatusBar() {
        return false;
    }

    /**
     * 是不是黑色主题
     *
     * @return 全屏展示
     */
    @Override
    public boolean fullscreen() {
        return false;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        AppManager.getInstance().popActivity(this);
    }


    /**
     * 点击空白处软键盘是否消失
     */
    protected boolean canTouch = true;
    /**
     * 指定控件，点击软键盘不消失，需要addView相关控件
     */
    protected boolean viewCanTouch = true;
    /**
     * editText注册-不在这里注册一下，软件盘消失时光标还会闪烁
     */
    private final List<EditText> editText = new ArrayList<>();
    /**
     * 指定控件，点击软键盘不消失
     */
    private final List<View> views = new ArrayList<>();

    /**
     * EditText与软键盘的控制
     * 如果点击空白处(非EditText)，关闭软键盘，隐藏光标
     *
     * @param editText
     */
    public void addEditText(EditText... editText) {
        this.editText.addAll(Arrays.asList(editText));
    }

    /**
     * 部分页面存在点击按钮，软键盘不取消的需求，把对应view添加到这里就好了
     *
     * @param view
     */
    public void addView(View view) {
        this.views.add(view);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {

        for (View v : views) {
            int[] leftTop = {0, 0};
            //获取输入框当前的location位置
            v.getLocationInWindow(leftTop);
            int left = leftTop[0];
            int top = leftTop[1];
            int bottom = top + v.getHeight();
            int right = left + v.getWidth();
            if ((ev.getX() > left && ev.getX() < right
                    && ev.getY() > top && ev.getY() < bottom
                    && v.getVisibility() == View.VISIBLE)) {
                viewCanTouch = false;
            }
        }

        if (!canTouch || !viewCanTouch) {
            viewCanTouch = true;
            return super.dispatchTouchEvent(ev);
        }
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            View v = getCurrentFocus();
            if (isShouldHideInput(v, ev)) {
                hideKeyboard(v);
            }
            return super.dispatchTouchEvent(ev);
        }
        // 必不可少，否则所有的组件都不会有TouchEvent了
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
        return onTouchEvent(ev);
    }

    /**
     * 强制隐藏键盘
     *
     * @param v
     */
    public void hideKeyboard(View v) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (null == v || null == v.getWindowToken()) {
        } else {
            imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
            for (EditText et : editText) {
                et.clearFocus();
            }
        }
    }

    public boolean isShouldHideInput(View v, MotionEvent event) {
        if (v != null && (v instanceof EditText)) {
            int[] leftTop = {0, 0};
            //获取输入框当前的location位置
            v.getLocationInWindow(leftTop);
            int left = leftTop[0];
            int top = leftTop[1];
            int bottom = top + v.getHeight();
            int right = left + v.getWidth();
            if ((event.getX() > left && event.getX() < right
                    && event.getY() > top && event.getY() < bottom)) {
                // 点击的是输入框区域，保留点击EditText的事件
                return false;
            } else {
                return true;
            }
        }
        return false;
    }

}
